#include "vpss_pipe_imp.h"
#include "sys_ctrl_mgr.h"
#include "guard.h"
#include "mpi_vpss.h"
using namespace Json;
using namespace detu_infra;

namespace detu_media
{

VpssPipeImp::VpssPipeImp(const VPSS_GRP grpId)
    : VpssPipe(), fPipeId(-1), fGrpId(grpId), fInited(false), fRef(0)
    , fMutex(MUTEX_RECURSIVE), fBindCfg(Value::null)
{
}

VpssPipeImp::~VpssPipeImp()
{
	if (isInited())
		deInit();
}

S_Result VpssPipeImp::init(const Json::Value& config)
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	do
	{
		fPipeId = (config.isMember("pipeId") && config["pipeId"].isIntegral()) ? config["pipeId"].asInt() : -1;
		if (config.isMember("bind"))
		{
			fBindCfg = config["bind"];
		}

		ret = S_OK;
		fInited = true;
	}
	while(0);

	return ret;
}

S_Result VpssPipeImp::deInit()
{
	Guard guard(fMutex);
	if (isStarted())
	{
		fRef = 1;
		stop();
	}
	fGrpId = -1;
	fPipeId = -1;
	fBindCfg.clear();
	fInited = false;
	
	return S_OK;
}

S_Result VpssPipeImp::start()
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	do
	{
		if (fRef < 0)
		{
			printf("start failed, fRef: %d < 0! grpId: %d, pipeId: %d\n", fRef, fGrpId, fPipeId);
			break;
		}
		
		if (fRef > 0)
		{
			ret = S_OK;
			break;
		}

		if (!isInited())
		{
			printf("grpId: %d, pipeId: %d not inited!\n", fGrpId, fPipeId);
			break;
		}

		SysCtrlMgr& sysCtrlMgr = *SysCtrlMgr::instance();
		if (S_OK != sysCtrlMgr.bind(fBindCfg))
		{
			printf("vpss bind failed! grpId: %d, pipeId: %d\n", fGrpId, fPipeId);
			break;
		}
		
		ret = S_OK;
	}
	while(0);

	if (S_OK == ret)
		fRef++;
	
	return ret;
}

S_Result VpssPipeImp::stop()
{
	Guard guard(fMutex);
	S_Result ret = S_ERROR;
	do
	{
		if (fRef < 1)
		{
			printf("stop failed, fRef: %d < 1! grpId: %d, pipeId: %d\n", fRef, fGrpId, fPipeId);
			break;
		}
		
		if (fRef > 1)
		{
			ret = S_OK;
			break;
		}

		if (!isInited())
		{
			printf("grpId: %d, pipeId: %d not inited!\n", fGrpId, fPipeId);
			break;
		}

		SysCtrlMgr& sysCtrlMgr = *SysCtrlMgr::instance();
		if (S_OK != sysCtrlMgr.unbind(fBindCfg))
		{
			printf("vpss unbind failed! grpId: %d, pipeId: %d\n", fGrpId, fPipeId);
			break;
		}
		
		ret = S_OK;
	}
	while(0);

	if (S_OK == ret)
		fRef--;
	
	return ret;
}

bool VpssPipeImp::isInited()
{
    return fInited;
}

bool VpssPipeImp::isStarted()
{
    return (fRef > 0);
}

S_Result VpssPipeImp::getId(int &id)
{
    id = fPipeId;

    return S_OK;
}

#if 0
S_Result VpssPipeImp::getVpssChnFrame(DT_VIDEO_FRAME_INFO_S* VideoFrameInfo, const Int32_t milliSec)
{
    Guard guard(fMutex);
	S_Result ret = S_ERROR;

    do
    {
        HI_S32 s32Ret = HI_MPI_VPSS_GetChnFrame(fGrpId, fPipeId, (VIDEO_FRAME_INFO_S*)VideoFrameInfo, milliSec);
        if(HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_VPSS_GetChnFrame failed! grpId: %d, pipeId: %d\n", fGrpId, fPipeId);
            break;
        }
        ret = S_OK;
    }
    while(0);

    return ret;
}
#endif

}
